package com.njym.payment.wxpay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import com.njym.entity.SysPaymentConfig;
import com.njym.entity.SysPaymentMode;
import com.njym.payment.wxpay.api.Util;
import com.njym.service.SysPaymentModeService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * @author zhy
 * @date 2019-04-10 16:52
 **/
@Component
public class GetWxPayClient {
	@Resource
	private SysPaymentModeService sysPaymentModeService;

	private Lock lock = new ReentrantLock();

	private Map<String, WxPayProperties> wxPayPropertiesMap = new HashMap<>();

	private Map<String, WxPayService> wxPayServiceHashMap = new HashMap<>();

	private Map<String, SysPaymentMode> sysPaymentModeMap = new HashMap<>();

	/**
	 * 获取openId
	 */
	public String getopendid(String code,WxPayConfig wxPayConfig) {
		String url = "https://api.weixin.qq.com/sns/oauth2/access_token"
			+ "?appid=AppId"
			+ "&secret=AppSecret"
			+ "&code=CODE"
			+ "&grant_type=authorization_code";
		url = url.replace("AppId", wxPayConfig.getAppId())
			.replace("AppSecret", "8a1b1799be62fc68f4047d82b73b3609")
            .replace("CODE", code);

		String str = Util.sendPost(url, null);
		JSONObject json =  JSONObject.parseObject(str);
		String openid = json.getString("openid");

		return openid;
	}

	/**
	 * 通过机构id查询相应的微信支付配置
	 *
	 * @param orgId
	 * @return WxPayProperties
	 */
	public WxPayProperties getWxPayProperties(String orgId) {
		WxPayProperties wxPayPropertiess = wxPayPropertiesMap.get(orgId);
		if (wxPayPropertiess != null) {
			return wxPayPropertiess;
		} else {
			lock.lock();
			WxPayProperties wxPayProperties;
			try {
				SysPaymentMode sysPaymentMode = sysPaymentModeService.selectModeIncludesConfigs(orgId, "wxpay");
				if (sysPaymentMode == null) {
					return null;
				}
				List<SysPaymentConfig> sysPaymentConfigList = sysPaymentMode.getSysPaymentConfigs();
				JSONObject jsonObj = new JSONObject();

				for (SysPaymentConfig sysPaymentConfig : sysPaymentConfigList) {
					String key = sysPaymentConfig.getConfigKey();
					String value = sysPaymentConfig.getConfigValue();
					jsonObj.put(key, value);
				}
				try {
					wxPayProperties = JSON.toJavaObject(jsonObj, WxPayProperties.class);
				}
				catch (Exception e) {
					e.printStackTrace();
					return null;
				}
				wxPayPropertiesMap.put(orgId, wxPayProperties);
			}
			finally {
				lock.unlock();
			}
			return wxPayProperties;
		}
	}

	public WxPayService getWxService(String orgId) {
		WxPayService wxPayServices = wxPayServiceHashMap.get(orgId);
		if (wxPayServices != null) {
			return wxPayServices;
		} else {
			lock.lock();
			WxPayService wxPayServicesa;
			try {
				SysPaymentMode sysPaymentMode = sysPaymentModeService.selectModeIncludesConfigs(orgId, "wxpay");
				if (sysPaymentMode == null) {
					return null;
				}
				List<SysPaymentConfig> sysPaymentConfigList = sysPaymentMode.getSysPaymentConfigs();
				JSONObject jsonObj = new JSONObject();

				for (SysPaymentConfig sysPaymentConfig : sysPaymentConfigList) {
					String key = sysPaymentConfig.getConfigKey();
					String value = sysPaymentConfig.getConfigValue();
					jsonObj.put(key, value);
				}
				WxPayProperties wxPayProperties;
				try {
					wxPayProperties = JSON.toJavaObject(jsonObj, WxPayProperties.class);
				}
				catch (Exception e) {
					e.printStackTrace();
					return null;
				}
				WxPayConfig payConfig = new WxPayConfig();
				payConfig.setAppId(StringUtils.trimToNull(wxPayProperties.getAppId()));
				payConfig.setMchId(StringUtils.trimToNull(wxPayProperties.getMchId()));
				payConfig.setMchKey(StringUtils.trimToNull(wxPayProperties.getMchKey()));
				payConfig.setSubAppId(StringUtils.trimToNull(wxPayProperties.getSubAppId()));
				payConfig.setSubMchId(StringUtils.trimToNull(wxPayProperties.getSubMchId()));
				payConfig.setKeyPath(StringUtils.trimToNull(wxPayProperties.getKeyPath()));
				payConfig.setNotifyUrl(StringUtils.trimToNull(wxPayProperties.getNotifyUrl()));

				wxPayServicesa = new WxPayServiceImpl();
				wxPayServicesa.setConfig(payConfig);
				wxPayServiceHashMap.put(orgId, wxPayServicesa);
			}
			finally {
				lock.unlock();
			}
			return wxPayServicesa;
		}
	}

	public SysPaymentMode getModeById(String orgId) {
		SysPaymentMode sysPaymentMode = sysPaymentModeMap.get(orgId);
		if (sysPaymentMode != null) {
			return sysPaymentMode;
		} else {
			lock.lock();
			SysPaymentMode sysPaymentModes;
			try {
				sysPaymentModes = sysPaymentModeService.selectModeIncludesConfigs(orgId, "wxpay");
				if (sysPaymentModes == null) {
					return null;
				}
				sysPaymentModeMap.put(orgId, sysPaymentModes);
			}
			finally {
				lock.unlock();
			}
			return sysPaymentModes;
		}
	}


}
